home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / net / netware / nwconn.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-03-20  |  38.0 KB  |  1,185 lines

  1. {$B-,V-,X+}
  2. UNIT nwConn;
  3.  
  4. INTERFACE
  5.  
  6. { Primary Functions:                    Interrupt: comments:
  7.  
  8.   AttachToFileServer                    (F100)
  9. * DetachFromFileServer                  (F101)
  10.   EnterLoginArea                        (F217/0A)
  11. * GetConnectionInformation              (F217/16)
  12. * GetConnectionNumber                   (DC..)
  13. * GetInternetAddress                    (F217/13)
  14. * GetObjectConnectionNumbers            (F217/15)
  15. * GetStationAddress                     (EE..)
  16. - GetStationsLoggedInformation          (F217/05) (5)
  17. - Login                                 (F217/00) (3)
  18. * LoginToFileserver                     (F217/14)  UNencrypted
  19. * LoginEncrToFileserver                 (F217/18)  encrypted
  20. * Logout                                (F219)
  21. * LogoutFromFileServer                  (F102)
  22. - MapUserToStationSet                   (F217/02) (4)
  23.  
  24. * EndOfJob                              (D6)      to be rewritten to F218
  25. * GetConnectionID                       (EF04)
  26.   GetConnectionIDtable                  (EF03)    (6)
  27. * GetDefaultConnectionID                (F002)
  28.   GetDriveConnectionID                  (EF02)
  29.   GetDriveFlag                          (EF01)
  30.   GetDriveHandle                        (EF00)
  31. * GetFileServerName                     (EF04)
  32.   GetNetwareShellVersion                (EA00)
  33.   GetNumberOfLocalDrives                (DB..)
  34. * GetPreferredConnectionID              (F001)
  35. * GetPrimaryConnectionID                (F005)
  36.   GetTaskMode                           (B503)
  37.   GetTaskModePointer                    (B504)
  38.   GetWorkstationEnvironment             (EAxx,xx>00) (2)
  39.   SetEndOfJobStatus                     (BB..)
  40.   SetNetwareErrorMode                   (DD..)
  41. * SetPreferredConnectionID              (F000)
  42.   SetPrimaryConnectionID                (F004)
  43.  
  44.   Secondary Functions:
  45.  
  46.   IsConnectionIDinUse                   (EF03)
  47. * GetUserAtConnection                   (GetConnectionInformation)
  48. * GetObjectLoginControl                 (nwBindry.ReadPropertyValue)
  49.  
  50. Notes: -Only functions marked with a * have been tested; others might work.
  51.        -(2): This function is an extension to EA00 GetNetwareShellVersion.
  52.              A function that returns all returned information from the call
  53.              EAxx,xx>00 is sometimes referred to as GetWShardwareAndOS.
  54.        -(6): This function returns the complete Connection ID table. The
  55.              partial function IsConnectionIDInUse has been moved to the
  56.              secondary function group.
  57.  
  58.        -NOT implemented in this API:
  59.         (3): This function has been replaced by F217/14 LoginToFileServer.
  60.         (4): Replaced by F217/15 GetObjectConnectionNumbers.
  61.         (5): Replaced by F217/16 GetConnectionInformation.
  62.  
  63.        -NW 386 can support up to 250 connections, NW 286 Max 100.
  64.        -Type TconnectionList=array[1..250] of byte (Declared in unit nwMisc)
  65.  
  66. Related functions in other units:
  67. ---------------------------------
  68. SendBroadcastMessage (nwMess) ; sends a message to a list of connections.
  69. }
  70. Uses nwMisc,nwBindry;
  71.  
  72. CONST
  73.   DRIVE_PERMANENT = $01; { Drive permanently assigned to fileserver directory }
  74.   DRIVE_TEMPORARY = $02; { Drive temporary assigned to FS dir. Released by EOJ }
  75.   DRIVE_NETWORK   = $03; { Normal drive mapping }
  76.   DRIVE_LOCAL     = $80; { Drive is local. ! By ORing with one of the above bits,
  77.                            it can be reassigned to a FS directory.                  }
  78.  
  79. Type
  80.   TconnIDTable=Record  { used by getConnectionIDtable }
  81.                SlotInUse       :Byte; { 0=Free, >0 : In use }
  82.                OrderNbr        :Byte;  { 1..8, order of servers in table,
  83.                                          sorted by network/node address.}
  84.                NetWorkNbr      :LongInt;
  85.                PhysNodeAddress :TnodeAddress; { 6 bytes hi-lo }
  86.                SocketNbr       :Word;         { receiving socket on server }
  87.                ReceiveTimeOut  :Word;
  88.                RouterPhysNAddr :TnodeAddress; { 6 bytes hi-lo }
  89.                PacketSeqNbr    :Byte;
  90.                ConnectionNumber:Byte; { this WS is known as connection x by this server,
  91.                                         FF:no connection }
  92.                ConnectionStatus:Byte; { FFh?/0?: connection functioning }
  93.                MaxTimeOut      :Word;
  94.                Filler          :array[1..5] of byte;
  95.                end;
  96.  
  97.   TloginControl=Record
  98.                 AccountDisabled           :boolean;
  99.                 AccountExpirationDate     :NovTimeRec; { dmy valid only }
  100.  
  101.                 MinimumPasswordLength     :byte;
  102.                 PasswordControlFlag       :byte;
  103.                 DaysBetweenPasswordChanges:word;
  104.                 PasswordExpirationDate    :NovTimeRec;
  105.                 LastLoginTime             :NovTimeRec; {dmy, hms valid only }
  106.                 GraceLoginsRemaining      :Byte;
  107.                 MaxGraceLoginsAllowed     :byte;
  108.                 BadLoginCount             :byte;
  109.                 AccountResetTime          :NovTimeRec; {dmy, hms valid only }
  110.                 LastIntruderAdress        :TinterNetworkAdress;
  111.  
  112.                 MaxConcurrentConnections  :byte;
  113.                 LoginTimes                :array[1..42] of byte;
  114.  
  115.                 unknown1                  :byte;
  116.                 unknown2                  :NovTimeRec;
  117.                 end;
  118.  
  119. Var result:word;
  120.  
  121. {BB.. [2.0/2.1/3.x]}
  122. Function SetEndOfJobStatus( EndOfJobFlag: Boolean ):Boolean;
  123. { When this function is called with EndOfJobFlag=False and control is returned
  124.   to the root COMMAND.COM, COMMAND.COM will NOT perform an EOJ action.     }
  125.  
  126. {F218 [2.15c+]}
  127. FUNCTION EndOfJob(All : Boolean):boolean;
  128. { forces an end of job
  129.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  130.   Ending a job unlocks and clears all locked or logged files and records.
  131.   It close all open network and local files and resets error and lock modes.
  132.   It also resets the workstation environment.                               }
  133.  
  134. {F219 [2.15c+]}
  135. Function Logout:boolean;
  136. {logout from all file servers, remains attached to Server, effective EOJ }
  137.  
  138. {DB.. [2.0/2.1/3.x]}
  139. Function GetNumberOfLocalDrives( Var drives:Byte ):Boolean;
  140.  
  141. {DC.. [2.0/2.1/3.x]}
  142. Function GetConnectionNumber(Var ConnectionNbr:byte):boolean;
  143. { returns connection number of requesting WS (1..100) }
  144.  
  145. {DD.. [2.0/2.1/3.x]}
  146. Function SetNetwareErrorMode( errMode:Byte):boolean;
  147. { Sets the shell's handling mode for dealing with netware errors.
  148.   0: default, INT 24 handler 'Abort, Retry, Fail';
  149.   1: a netware error number is returned in AL;
  150.   2: the netware error number is translated to a DOS error number,
  151.      this number is returned.
  152.   An EOJ resets the errormode to 0.                                      }
  153.  
  154. {E3../0A [2.0/2.1/3.x]}
  155. Function EnterLoginArea( LoginSubDirName:String;
  156.                          numberOfLocalDrives:Byte ):boolean;
  157. { Changes the login directory. Used by boot-proms.
  158.   LoginSubDirName contains the name of a sub directory under SYS:LOGIN
  159.   (e.g. 'V330' means login.exe is to be executed in directory SYS:LOGIN\V330)}
  160.  
  161. {F217/13 [2.15c+]}
  162. Function GetInternetAddress( ConnNbr : byte;
  163.                               var NetworkNumber:LongInt; { 4 bytes }
  164.                               var physNodeAddress:TnodeAddress; { 6 bytes }
  165.                               Var socketNumber : Word
  166.                               ):boolean;
  167.  
  168. {F217/14 [2.15c+] UNENCRYPTED}
  169. Function LoginToFileServer( objName:String; objType:word;
  170.                             password : string              ):boolean;
  171.  
  172. {F217/18 [2.15c+] ENCRYPTED}
  173. FUNCTION LoginEncrToFileServer(ObjName: String; ObjType: Word;
  174.                                PassWord: String            ): Boolean;
  175.  
  176. {F217/15 [2.15c+]}
  177. Function GetObjectConnectionNumbers( objName:String; objType:Word;
  178.                                      Var numberOfConnections: Byte;
  179.                                      Var connections: TconnectionList ):boolean;
  180. { returns a list of connectionnumbers where objects of the desired type and
  181.   name are logged in.
  182.   Tconnectionlist is defined as an array[1..100] of byte. Max connections for
  183.   Netware 286 = 100. Netware 386 allows more than 100 connections.
  184.   The NumberofConnections is greater or equal to 0,
  185.   if >0 then connections[1..NumberOfConnections] contains a list of connections. }
  186.  
  187. {F217/16 [2.15c+]}
  188. Function GetConnectionInforMation (ConnectionNbr:byte;
  189.                                    Var objName:String;
  190.                                    Var objType:Word;
  191.                                    Var objId:LongInt;
  192.                                    Var LoginTime:NovTimeRec ):boolean;
  193.  
  194. {EA00 [2.0/2.1/3.x]}
  195. Function GetNetwareShellVersion( Var MajorVersion,MinorVersion,
  196.                                      RevisionLevel :Byte       ):Boolean;
  197. { Returns information about a WS environment. Queries shell.
  198.   See also: GetWorkstationEnvironment                                   }
  199.  
  200. {EAxx,xx>00 [2.0/2.1/3.x]}
  201. Function GetWorkstationEnvironment(Var OStype,OSversion,
  202.                               HardwareType,ShortHWType:String):Boolean;
  203.  
  204. {EE.. [2.0/2.1/3.x]}
  205. FUNCTION GetStationAddress( var physicalNodeAddress: TNodeAddress ):boolean;
  206. { Get the physical station address (6 bytes hi-endian) }
  207.  
  208. {EF00 [2.0/2.1/3.x]}
  209. Function GetDriveHandle( Drive:Byte; Var Handle:Byte ):boolean;
  210. { The call returns a pointer to the shell's Drive Handle Table. (32 bytes)
  211.   (Drives A..Z and temporary drives [\]^_' )
  212.   If a drive has been assigned a directory handle on the file server,
  213.   the handle can be found in the DHT at the position corresponding with the drive letter.}
  214.  
  215. {EF01 [2.0/2.1/3.x]}
  216. Function GetDriveFlag( Drive:Byte; Var Flag:Byte ):Boolean;
  217. { This call returns a pointer to the shell's Drive Flag Table (32 Bytes)
  218.   Each entry indicates a drive's status (permanent,temporary,local,unassigned)
  219.   For further explanation see the DRIVE_xxx constants.}
  220.  
  221. {EF02 [2.0/2.1/3.x]}
  222. Function getDriveConnectionID( Drive:Byte; Var connID:Byte):boolean;
  223. { returns the servernumber (1..8) associated with a drive. }
  224.  
  225. {EF03 [2.0/2.1/3.x]}
  226. Function GetConnectionIDTable( connID: byte ; Var table: TconnIDtable ):boolean;
  227.  
  228. {EF04 [2.0/2.1/3.x]}
  229. Function GetConnectionID( serverName: String; Var connID: byte):boolean;
  230.  
  231. {EF04 [2.0/2.1/3.x]}
  232. Function GetFileServerName( connectionID : byte; var ServerName : string):boolean;
  233. { get name of file server. file server number must be in range [1..8] }
  234.  
  235. {F000 [2.0/2.1/3.x]}
  236. Function SetPreferredConnectionID( connectionID :byte ):boolean;
  237. { The preferred server is the default server to which the request packets are sent.
  238.   Calls are routed to the preferred server. (IF explicitly set!).
  239.   If the preferred server was not set then the requests are routed to
  240.   the server that is attached to the current drive. If the current
  241.   drive is a local drive then the requests will be sent to the primary
  242.   server (mostly the server the shell initially attached to.)            }
  243.  
  244. {F001 [2.0/2.1/3.x]}
  245. Function GetPreferredConnectionID(var connID : byte):boolean;
  246.  
  247. {F002 [2.0/2.1/3.x]}
  248. FUNCTION GetDefaultConnectionID(var connID :byte):boolean;
  249. { Returns the connection ID of the file server to which
  250.   the packets are currently being sent.                                    }
  251.  
  252. {F004 [2.0/2.1/3.x]}
  253. FUNCTION SetPrimaryConnectionID( primaryConnectionID :Byte ):boolean;
  254.  
  255. {F005 [2.0/2.1/3.x]}
  256. FUNCTION GetPrimaryConnectionID(var connID :byte ):boolean;
  257. { returns connection number of default file server (1..8) }
  258.  
  259. {F100 [2.0/2.1/3.x]}
  260. function AttachToFileServer( ConnID : Byte) : Boolean;
  261. { Create an attachment between a server and a workstation }
  262. { Does not Login the workstation }
  263.  
  264. {F101 [2.0/2.1/3.x]}
  265. Function DetachFromFileServer( connectionID:byte ):boolean;
  266. { removes server from shell's server table. Relinquishes the
  267.   fileserver connection number and breaks the connection.         }
  268.  
  269. {F102 [2.0/2.1/3.x]}
  270. Function LogoutFromFileServer(var ConnectionID: byte):boolean;
  271. {logout from one file server}
  272.  
  273.  
  274. {B503: (Shell version >=3.01)}
  275. Function GetTaskMode( Var taskMode:Byte):boolean;
  276.  
  277. {B504: (shell version >=3.01)}
  278. Function GetTaskModePointer( PtaskMode:Pointer ):boolean;
  279.  
  280. {***** secondary Functions, Result variable is not used*******************}
  281.  
  282. {EF03 [2.0/2.1/3.x] secondary Function }
  283. Function IsConnectionIDinUse( connID: byte ):boolean;
  284.  
  285. Function GetUserAtConnection( ConnectionNbr:byte; var username: string):boolean;
  286. {This function provides a short method of obtaining just the USERID.}
  287.  
  288. Function GetEffectiveConnectionID(Var connId:byte):boolean;
  289. {What server are the requests currently sent to? }
  290.  
  291. Function GetObjectLoginControl(ObjName:string; ObjType:word;
  292.                                VAR LoginControlInfo:TloginControl):boolean;
  293.  
  294. IMPLEMENTATION{=============================================================}
  295.  
  296. USES Dos;
  297.  
  298. Var UnitReqBuffer:array[1..576] of byte;
  299.     UnitReplyBuffer:array[1..576] of byte;
  300.     UnitRegs:registers;
  301.  
  302. Procedure F2SystemCall(subf:byte;req_size,rep_size:word);
  303. begin
  304. With UnitRegs
  305.  do begin
  306.     DS := Seg(UnitReqBuffer);  SI := Ofs(UnitReqBuffer);   CX := Req_size;
  307.     ES := Seg(UnitReplyBuffer);DI := Ofs(UnitReplyBuffer); DX := rep_size;
  308.     AH := $F2; AL := subf;
  309.     MSDOS(UnitRegs);
  310.     Result:=al;
  311.     end;
  312. end;
  313.  
  314.  
  315. {F000 [2.0/2.1/3.x]}
  316. Function SetPreferredConnectionID( connectionID :byte ):boolean;
  317. { The preferred server is the default server to which the request
  318.   packets are sent.
  319.   Calls are routed to the preferred server. (IF explicitly set!).
  320.   If the preferred server was not set then the requests are routed to
  321.   the server that is attached to the current drive. If the current
  322.   drive is a local drive then the requests will be sent to the primary
  323.   server (mostly the server the shell initially attached to.)            }
  324. var regs : registers;
  325. begin
  326.  regs.ax := $F000;
  327.  regs.dl := connectionID; { 1..8, 0 to clear }
  328.  msdos(regs);
  329.  result:=0;
  330.  SetPreferredConnectionID:=TRUE;
  331. end;
  332.  
  333. {F004 [2.0/2.1/3.x]}
  334. FUNCTION SetPrimaryConnectionID( primaryConnectionID :Byte ):boolean;
  335. var regs : registers;
  336. begin
  337.  regs.ax := $F004;
  338.  regs.dl := primaryConnectionID; { 1..8, or 0 to clear }
  339.  msdos(regs);
  340.  result:=0;
  341.  SetPrimaryConnectionID:=TRUE;
  342. end;
  343.  
  344. {F005 [2.0/2.1/3.x]}
  345. FUNCTION GetPrimaryConnectionID(var connID :byte ):boolean;
  346. { returns connection number of the primary file server (1..8) }
  347. var regs : registers;
  348. begin
  349.  regs.ax := $F005;
  350.  msdos(regs);
  351.  connID := regs.al;
  352.  result:=0;
  353.  GetPrimaryConnectionID:=((connID>0) and (connID<9))
  354. end;
  355.  
  356. {F002 [2.0/2.1/3.x]}
  357. FUNCTION GetDefaultConnectionID(var connID :byte):boolean;
  358. { Returns the connection ID of the file server to which
  359.   the packets are currently being sent.                                    }
  360. var regs : registers;
  361. begin
  362.  regs.ax := $F002;
  363.  msdos(regs);
  364.  connID := regs.al; { 1..8 }
  365.  result:=0;
  366.  GetDefaultConnectionID:=((connID>0) and (connID<9))
  367. end;
  368.  
  369. {F001 [2.0/2.1/3.x]}
  370. Function GetPreferredConnectionID(var connID : byte):boolean;
  371. var regs : registers;
  372. begin
  373.  regs.ax := $F001;
  374.  msdos(regs);
  375.  connID := regs.al; { 1..8, or 0 if the preferred server was not set }
  376.  { The preferred coneection is reset to 0 by an EOJ. }
  377.  result:=0;
  378.  GetPreferredConnectionID:=((connID>0) and (connID<9))
  379. end;
  380.  
  381.  
  382.  
  383. {EF03 [2.0/2.1/3.x]}
  384. Function GetConnectionIDTable( connID: byte ; Var table: TconnIDtable ):boolean;
  385. Type ptarr=^tarr;
  386.      tarr=array[0..8*32] of byte;
  387. Var regs:registers;
  388. begin
  389. If ((connID<1) or (ConnID>8))
  390.  then Result:=$FF
  391.  else begin
  392.       regs.ax:=$EF03;
  393.       MsDos(regs);
  394.       move( ptarr(Ptr(regs.es,regs.si))^[(connID-1)*32], table, 32 );
  395.       table.socketNbr:=swap(table.socketNbr); { force lo-hi }
  396.       table.NetworkNbr:=Lswap(table.NetworkNbr); { force lo-hi }
  397.       table.ReceiveTimeOut:=swap(table.ReceiveTimeOut); { force lo-hi }
  398.       table.MaxTimeOut:=swap(table.MaxTimeOut); { force lo-hi }
  399.       Result:=$00;
  400.       end;
  401. GetConnectionIDTable:=(Result=0);
  402. end;
  403.  
  404. {EF04 [2.0/2.1/3.x]}
  405. Function GetConnectionID( serverName: String; Var connID: byte):boolean;
  406. var regs       : registers;
  407.     name_table : array [1..8*48] of Byte;
  408.     server     : array [1..8] of string;
  409.     count      : integer;
  410.     p          : ^byte;
  411.     lname      : string;
  412. begin
  413.  lname:=serverName; UpString(lname);
  414.  regs.ax := $EF04;
  415.  msdos(regs);
  416.  result:=regs.AL;
  417.  
  418.  p := ptr(regs.es, regs.si); { pointer to shell's server name table. }
  419.  move(p^,name_table,8*48);
  420. for count := 1 to 8 do server[count] := '';
  421.  { name table 8 entries by 48 decimal chars. Asciiz strings. }
  422. for count := 0 to 7
  423.   do ZstrCopy(server[count+1],name_table[1+ count*48],48);
  424.  
  425. count:=1;
  426. While ((count<9) and (server[count]<>lName))
  427.  do inc(count);
  428. If count=9
  429.  then begin
  430.       Result:=$FF; { server name not found }
  431.       GetConnectionID:=False
  432.       end
  433.  else begin
  434.       connID:=count;
  435.       Result:=$00;
  436.       GetConnectionID:=TRUE;
  437.       end;
  438. end;
  439.  
  440. {EF04 [2.0/2.1/3.x]}
  441. Function GetFileServerName( connectionID : byte; var ServerName : string):boolean;
  442. { get name of file server. file server number must be in range [1..8] }
  443. var regs       : registers;
  444.     name_table : array [1..8*48] of Byte;
  445.     server     : array [1..8] of string;
  446.     count      : integer;
  447.     p          : ^byte;
  448. begin
  449.  regs.ax := $EF04;
  450.  msdos(regs);
  451.  result:=regs.AL;
  452.  
  453.  p := ptr(regs.es, regs.si); { pointer to shell's server name table. }
  454.  move(p^,name_table,8*48);
  455. for count := 1 to 8 do server[count] := '';
  456.  { name table 8 entries by 48 decimal chars. Asciiz strings. }
  457. for count := 0 to 7
  458.   do ZstrCopy(server[count+1],name_table[1+ count*48],48);
  459. if ((connectionID<1) or (connectionID>8))
  460.   then serverName:= server[1]
  461.   else ServerName := server[connectionID];
  462. IF ServerName=''
  463.  then result:=$FF
  464.  else result:=$00;
  465. GetFileServerName:=result=0;
  466. end;
  467.  
  468.  
  469. {F100 [2.0/2.1/3.x]}
  470. function AttachToFileServer( ConnID : Byte) : Boolean;
  471. { Create an attachment between a server and a workstation }
  472. { Does not Login the workstation }
  473. Var NovRegs:Registers;
  474. begin
  475. with NovRegs
  476. do begin
  477.    AX := $F100;
  478.    DL := ConnID;
  479.    MsDos(NovRegs);
  480.    Result := AL;
  481.    end;
  482. AttachToFileServer:=(Result=0);
  483. { possible return codes:
  484.   F8 already attached to server; F9 No free connection slots at server;
  485.   FA no more server slots; FE Server Bindery Locked;
  486.   FF No response from server }
  487. end;
  488.  
  489. {F101 [2.0/2.1/3.x]}
  490. Function DetachFromFileServer( connectionID:byte ):boolean;
  491. { removes server from shell's server table. Relinquishes the
  492.   fileserver connection number and breaks the connection.         }
  493. var regs : registers;
  494. begin
  495.  regs.ax := $F101;
  496.  regs.dl := connectionID; { 1..8 }
  497.  msdos(regs);
  498.  result := regs.al;
  499.  DetachFromFileServer:=(result=0);
  500. { returncodes: 00 successful; FF Connection Doesn't exist }
  501. end;
  502.  
  503. {DC.. [2.0/2.1/3.x]}
  504. Function GetConnectionNumber(Var ConnectionNbr:byte):boolean;
  505. { returns connection number of requesting WS (1..100) }
  506. var regs:Registers;
  507. begin
  508. regs.Ah:=$DC;
  509. MsDos(regs);
  510. ConnectionNbr:=Regs.AL; { logical WS connection # }
  511. { cl= first digit of logical conn #, ch= second digit of conn# }
  512. result:=0;
  513. GetConnectionNumber:=true;
  514. end;
  515.  
  516.  
  517. {F217/16 [2.15c+]}
  518. Function GetConnectionInformation (ConnectionNbr:byte;
  519.                                    Var objName:String;
  520.                                    Var objType:Word;
  521.                                    Var objId:LongInt;
  522.                                    Var LoginTime:NovTimeRec ):boolean;
  523. Var
  524.   I,X            : Integer;
  525.   RequestBuffer  : Record
  526.                    PacketLength : Integer;
  527.                    FunctionVal  : Byte;
  528.                    _ConnectionNo : Byte;  { 1..100, nw286 needs this info }
  529.                    End        ABSOLUTE UnitReqBuffer;
  530.   ReplyBuffer    : Record
  531.                    _objId        :LongInt;  { hi-lo }
  532.                    _ObjType     : word;     { hi-lo }
  533.                    _ObjName     : Array [1..48] of Byte;
  534.                    _LoginTime    : NovTimeRec;
  535.                    Reserved:word;
  536.                    End        ABSOLUTE UnitReplyBuffer;
  537. Begin
  538. With RequestBuffer
  539. Do Begin
  540.    PacketLength := 2;
  541.    FunctionVal := $16;
  542.    _ConnectionNo := ConnectionNbr;
  543.    End;
  544. F2SystemCall($17,SizeOf(requestBuffer),SizeOf(ReplyBuffer));
  545. If Result = 0
  546.  Then Begin
  547.       With ReplyBuffer
  548.       Do Begin
  549.          ZstrCopy(ObjName,_objName,48);
  550.          ObjId:=Lswap(_objId);
  551.          ObjType:=swap(_objType);
  552.          logintime:=_logintime;
  553.          End;
  554.       End;
  555. { patch to have a NIL object return an error. }
  556. if objName='' then result:=$FD; { no_such_connection }
  557. GetConnectionInformation:=(result=0);
  558. End { GetConnectInfo };
  559.  
  560.  
  561.  
  562. {F217/14 [2.15c+,unencrypted]}
  563. Function LoginToFileServer( objName:String; objType:word;
  564.                             password : string             ):boolean;
  565. Var req  :record
  566.           len      :word;
  567.           subFunc  :byte;
  568.           _objType :Word; { hi-lo }
  569.           _objName :String[47]; { asciiz?  }
  570.           _objPassw:String[127]; { allowed to be '' }
  571.           end            ABSOLUTE UnitReqBuffer;
  572. Begin
  573. WITH req
  574. do begin
  575.    len:=SizeOf(req)-2;
  576.    subFunc:=$14;
  577.    _objType:=swap(objType);
  578.    PStrCopy(_objName,objName,47); _objName[47]:=#0; UpString(_objName);
  579.    PStrCopy(_objPassw,password,127); UpString(_objPassw);
  580.    end;
  581. F2SystemCall($17,SizeOf(req),0);
  582. LoginToFileServer:=(result=0)
  583. end;
  584.  
  585.  
  586. {F217/18 [3.x]}
  587. FUNCTION LoginEncrToFileServer(ObjName: String; ObjType: Word; PassWord: String): Boolean;
  588. { assumes the current effective server = the server to login to. }
  589.  
  590.  
  591.    FUNCTION LoginEncrypted(ObjName : String; ObjType : Word; VAR key : TencryptionKey): Boolean;
  592.    VAR req : RECORD
  593.              BufLen  : Word;
  594.              _func   : Byte;
  595.              _key    : TencryptionKey;
  596.              _ObjType: Word;
  597.              _ObjName: String[48];
  598.              End                  ABSOLUTE UnitReqBuffer;
  599.    Begin
  600.    With req
  601.     do Begin
  602.        _func := $18;
  603.        _key  := key;
  604.        _ObjType := Swap(objType);
  605.        PstrCopy(_ObjName,ObjName,48); UpString(_ObjName);
  606.        if ObjName[0]<#48
  607.          then _objName[0]:=objName[0]
  608.          else _objname[0]:=#48;
  609.        BufLen:=ord(_ObjName[0])+12;
  610.        End;
  611.    F2SystemCall($17,SizeOf(req),0);
  612.    LoginEncrypted:=(result=0);
  613.    End;
  614.  
  615. VAR
  616.   key : TencryptionKey;
  617.   ObjId:LongInt;
  618.   _pw:string;
  619.   _lpw:Byte;
  620.  
  621. Begin
  622. UpString(password);
  623. _pw:=password;if _pw[0]>#127 Then _pw[0]:=#127;
  624. _lpw:=length(password);
  625. if _lpw=0 Then _pw:=#0;
  626.  
  627. IF GetEncryptionKey(key)
  628.  Then Begin
  629.       writeln('getencryptionkey: OK');
  630.       IF GetBinderyObjectId(objName,objType,ObjId)
  631.        Then Begin
  632.             EncryptPassword(objId,_pw,key);
  633.             writeln('encryptpassword: OK');
  634.             LoginEncrypted(ObjName, ObjType, key);
  635.             End;
  636.       End
  637.  Else begin
  638.       writeln('Getencryptionkey failed. trying unencrypted login..');
  639.       LoginToFileServer(ObjName, ObjType, Password);
  640.       end;
  641.  
  642. LoginEncrToFileServer:= (result=0);
  643. End;
  644.  
  645.  
  646. {F219 [2.15c+]}
  647. Function Logout:boolean;
  648. {logout from all file servers, remains attached to Server, effective EOJ }
  649. begin
  650.  F2SystemCall($19,0,0);
  651. end;
  652.  
  653.  
  654. {F102 [2.0/2.1/3.x]}
  655. Function LogoutFromFileServer(var ConnectionID: byte):boolean;
  656. {logout from one file server}
  657. var regs : registers;
  658. begin
  659.  regs.ah := $F1;
  660.  regs.al := $02;
  661.  regs.dl := connectionID;
  662.  msdos(regs);
  663.  result:=00;
  664.  LogoutFromFileServer:=True;
  665. end;
  666.  
  667. {EE.. [2.0/2.1/3.x]}
  668. FUNCTION GetStationAddress( var physicalNodeAddress: TNodeAddress ):boolean;
  669. { Get the physical station address (6 bytes hi-endian) }
  670. Var Regs              :Registers;
  671. Begin
  672.  {Get the physical address from the Network Card}
  673.  Regs.Ah := $EE;
  674.  MsDos(Regs);
  675.  result:=Regs.AL;
  676.  {nw node= CX BX AX hi-endian}
  677.  physicalNodeAddress[1]:=Regs.CH;
  678.  physicalNodeAddress[2]:=Regs.CL;
  679.  physicalNodeAddress[3]:=Regs.bh;
  680.  physicalNodeAddress[4]:=Regs.bl;
  681.  physicalNodeAddress[5]:=Regs.ah;
  682.  physicalNodeAddress[6]:=Regs.al;
  683.  result := 0;
  684.  GetStationAddress:=true;
  685. End;
  686.  
  687.  
  688. {F217/13 [2.15c+]}
  689. Function GetInternetAddress( ConnNbr : byte;
  690.                               var NetworkNumber:LongInt; { 4 bytes }
  691.                               var physNodeAddress:TnodeAddress; { 6 bytes }
  692.                               Var socketNumber : Word
  693.                               ):boolean;
  694. Var  Request_buffer : record
  695.                      length      : word;
  696.                      subfunction : byte;
  697.                      connection  : byte;
  698.                      end            ABSOLUTE UnitReqBuffer;
  699.       Reply_Buffer : record
  700.                      network : LongInt; { array [1..4] of byte } { hi-lo }
  701.                      node    : array [1..6] of byte;             { hi-lo }
  702.                      socket  : word; { array [1..2] of byte }    { hi-lo }
  703.                      end            ABSOLUTE UnitReplyBuffer;
  704. BEGIN
  705. With request_buffer
  706. do begin
  707.    length := 2;
  708.    subfunction := $13;
  709.    connection := ConnNbr;
  710.    end;
  711. F2SystemCall($17,SizeOf(request_buffer),SizeOf(Reply_buffer));
  712. if result = 0
  713. then With reply_buffer
  714.       do begin
  715.          NetWorkNumber:=Lswap(network); { force lo-hi }
  716.          move(node,physNodeAddress,6);  { _is_ and stays hi-lo }
  717.          socketNumber:=swap(socket);    { force lo-hi }
  718.          end;
  719. GetInternetAddress:=(result=0);
  720. end;
  721.  
  722. {D6.. [2.0/2.1/3.x]}
  723. FUNCTION EndOfJob(All : Boolean):boolean;
  724. { forces an end of job
  725.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  726.   Ending a job unlocks and clears all locked or logged files and records.
  727.   It close all open network and local files and resets error and lock modes.
  728.   It also resets the workstation environment.                               }
  729. Var NovRegs:Registers;
  730. BEGIN
  731. with NovRegs
  732. do begin
  733.    AH := $D6;
  734.    if All
  735.     then BX := $FFFF
  736.     else BX := $00;
  737.    end;
  738. MsDos(NovRegs);
  739. Result:=$00;
  740. EndOfJob:=True;
  741. end;
  742.  
  743. {$IFDEF NewCalls}
  744.  
  745. {F218 [2.15c+]}
  746. FUNCTION EndOfJob(All : Boolean):boolean;
  747. { forces an end of job
  748.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  749.   Ending a job unlocks and clears all locked or logged files and records.
  750.   It close all open network and local files and resets error and lock modes.
  751.   It also resets the workstation environment.                               }
  752. Var req:record
  753.         len:word;
  754.         _all:word;
  755.         end ABSOLUTE UnitReqBuffer;
  756.    { ERR: unclear how the req buffer should be... }
  757. BEGIN
  758. if All
  759.  then req._all := $FFFF
  760.  else req._all := $0000;
  761. req.len:=2;
  762. F2SystemCall($18,2,0);
  763. Result:=$00;
  764. EndOfJob:=True;
  765. end;
  766.  
  767. {$ENDIF}
  768.  
  769.  
  770. {E3../0A [2.0/2.1/3.x]}
  771. Function EnterLoginArea( LoginSubDirName:String;
  772.                          numberOfLocalDrives:Byte ):boolean;
  773. { Changes the login directory. Used by boot-proms.
  774.   LoginSubDirName contains the name of a sub directory under SYS:LOGIN
  775.   (e.g. 'V330' means login.exe is to be executed in directory SYS:LOGIN\V330)}
  776. Var regs:registers;
  777. Var req  :record
  778.           len:word;
  779.           subFunc:byte;
  780.           _numLocDr:Byte;
  781.           _subDirName:String[255];
  782.           end;
  783.     reply:record
  784.           len:word;
  785.           end;
  786. Begin
  787. WITH req
  788. do begin
  789.    len:=SizeOf(req)-2;
  790.    subFunc:=$0A;
  791.    _numLocDr:=numberOfLocalDrives;
  792.    PstrCopy(_subDirName,LoginSubDirName,255); UpString(_subDirName);
  793.    end;
  794. Reply.len:=$00;
  795. With regs
  796. do begin
  797.    AH:=$E3;
  798.    Ds:=seg(Req);
  799.    si:=ofs(Req);
  800.    Es:=seg(Reply);
  801.    di:=ofs(Reply);
  802.    MsDos(regs);
  803.    result:=AL;
  804.    end;
  805. EnterLoginArea:=(result=0)
  806. end;
  807.  
  808. {F217/15 [2.15c+]}
  809. Function GetObjectConnectionNumbers( objName:String; objType:Word;
  810.                                      Var numberOfConnections: Byte;
  811.                                      Var connections: TconnectionList ):boolean;
  812. { returns a list of connectionnumbers where objects of the desired type and
  813.   name are logged in.
  814.   Tconnectionlist is defined as an array[1..100] of byte. Max connections for
  815.   Netware 286 = 100. Netware 386 allows more than 100 connections.
  816.   If you pass a bad Objectname or the object is not logged in, the errorcode
  817.   is NOT set to NO_SUCH_OBJECT ($FC), but GetObjectConnectionNumbers returns 0.}
  818. Var req  :record
  819.           len:word;
  820.           subFunc:byte;
  821.           _objType:Word; { hi-lo}
  822.           _objName:String[47];
  823.           end               ABSOLUTE UnitReqBuffer;
  824.     reply:record
  825.           _NbrOfConn:Byte;
  826.           _connList:TconnectionList
  827.           end               ABSOLUTE UnitReplyBuffer;
  828. Begin
  829. WITH req
  830. do begin
  831.    len:=SizeOf(req)-2;
  832.    subFunc:=$15;
  833.    PstrCopy(_objName,objName,47); _objname[47]:=#0; UpString(_objName);
  834.    _objType:=swap(objType);
  835.    end;
  836. F2SystemCall($17,SizeOf(req),SizeOf(reply));
  837. With reply
  838. do begin
  839.    connections:=_connList;
  840.    NumberOfConnections:=_NbrOfConn;
  841.    end;
  842. getObjectConnectionNumbers:=(result=0)
  843. end;
  844.  
  845. {EF00 [2.0/2.1/3.x]}
  846. Function GetDriveHandle( Drive:Byte; Var Handle:Byte ):boolean;
  847. { The call returns a pointer to the shell's Drive Handle Table. (32 bytes)
  848.   (Drives A..Z and temporary drives [\]^_' )
  849.   If a drive has been assigned a directory handle on the file server,
  850.   the handle can be found in the DHT at the position corresponding with the drive letter.}
  851. Type pArr=^arr;
  852.      arr=array[0..31] of byte;
  853. Var regs:registers;
  854.     Udrive:char;
  855. begin
  856. regs.ax:=$EF00;
  857. MsDos(regs);
  858. if Drive>31
  859.  then result:=$0105
  860.  else begin
  861.       Handle:=Parr(Ptr(Regs.Es,Regs.Si))^[Drive];
  862.       Result:=0;
  863.       end;
  864. GetDriveHandle:=(Result=0);
  865. end;
  866.  
  867. {EF01 [2.0/2.1/3.x]}
  868. Function GetDriveFlag( Drive:Byte; Var Flag:Byte ):Boolean;
  869. { This call returns a pointer to the shell's Drive Flag Table (32 Bytes)
  870.   Each entry indicates a drive's status (permanent,temporary,local,unassigned)
  871.   For further explanation see the DRIVE_xxx constants.}
  872. Type pArr=^arr;
  873.      arr=array[0..31] of byte;
  874. Var regs:registers;
  875. begin
  876. regs.ax:=$EF01;
  877. MsDos(Regs);
  878. If Drive>31
  879.   then result:=$0105
  880.   else begin
  881.        Flag:=Parr(Ptr(Regs.es,regs.si))^[Drive];
  882.        Result:=0;
  883.        end;
  884. GetDriveFlag:=(Result=0);
  885. end;
  886.  
  887. {EF02 [2.0/2.1/3.x]}
  888. Function getDriveConnectionID( Drive:Byte; Var connID:Byte):boolean;
  889. { returns the servernumber (1..8) associated with a drive. }
  890. Type pArr=^arr;
  891.      arr=array[0..31] of byte;
  892. Var regs:registers;
  893. begin
  894. regs.ax:=$EF02;
  895. MsDos(Regs);
  896. If Drive>31
  897.  then result:=$0105
  898.  else begin
  899.       connID:=Parr(Ptr(Regs.es,regs.si))^[Drive];
  900.       Result:=0;
  901.       end;
  902. GetDriveConnectionID:=(Result=0);
  903. end;
  904.  
  905. {EA00 [2.0/2.1/3.x]}
  906. Function GetNetwareShellVersion( Var MajorVersion,MinorVersion,
  907.                                      RevisionLevel :Byte       ):Boolean;
  908. { Returns information about a WS environment. Queries shell.
  909.   See also: GetWorkstationEnvironment                                   }
  910. Var regs:Registers;
  911.     reply:record
  912.           stringz4:array[1..4*32] of byte;
  913.           end;
  914. Begin
  915. With regs
  916. do begin
  917.    AX:=$EA00;
  918.    ES:=seg(reply);
  919.    DI:=ofs(reply);
  920.    MsDos(regs);
  921.    MajorVersion:=BH;
  922.    MinorVersion:=BL;
  923.    { shell version>=3.00 : }
  924.    { CH = Shell Type. 0=conventional, 1= expanded, 2= extended }
  925.    RevisionLevel:=CL; { 1=A,2=B etc. }
  926.    end;
  927. Result:=$00;
  928. GetNetwareShellVersion:=True;
  929. end;
  930.  
  931. {EAxx,xx>00 [2.0/2.1/3.x] (shell version >=3.00) }
  932. Function GetWorkstationEnvironment(Var OStype,OSversion,
  933.                               HardwareType,ShortHWType:String):Boolean;
  934. Var regs:Registers;
  935.     reply:record
  936.           stringz4:array[1..4*32] of char;
  937.           end;
  938.     sNo,k:Byte;
  939. Begin
  940. With regs
  941. do begin
  942.    AX:=$EA01;
  943.    BX:=$00;
  944.    ES:=seg(reply);
  945.    DI:=ofs(reply);
  946.    MsDos(regs);
  947.    end;
  948. OStype:='';
  949. OSVersion:='';
  950. HardwareType:='';
  951. ShortHWtype:='';
  952. sNo:=0;k:=0;
  953. With reply
  954. do begin
  955.    while sNo<4
  956.    do begin
  957.       inc(k);
  958.       while ((k<128) and (stringz4[k]<>#0))
  959.       do begin
  960.          Case sNo of
  961.           0:OStype:=OStype+stringz4[k];
  962.           1:OSversion:=OSversion+stringz4[k];
  963.           2:HardwareType:=HardwareType+stringz4[k];
  964.           3:ShortHWtype:=ShortHWtype+stringz4[k];
  965.          end; {case}
  966.          inc(k);
  967.          end;
  968.       inc(Sno);
  969.       end;
  970.    end;
  971. Result:=$00;
  972. GetWorkstationEnvironment:=True;
  973. end;
  974.  
  975. {DD.. [2.0/2.1/3.x]}
  976. Function SetNetwareErrorMode( errMode:Byte):boolean;
  977. { Sets the shell's handling mode for dealing with netware errors.
  978.   0: default, INT 24 handler 'Abort, Retry, Fail';
  979.   1: a netware error number is returned in AL;
  980.   2: the netware error number is translated to a DOS error number,
  981.      this number is returned.
  982.   An EOJ resets the errormode to 0.                                      }
  983. Var regs:registers;
  984. begin
  985. Regs.AH:=$DD;
  986. Regs.DL:=errMode;
  987. MsDos(Regs);
  988. { regs.al now contains previous error mode }
  989. Result:=$00;
  990. SetNetWareErrorMode:=True;
  991. end;
  992.  
  993. {BB.. [2.0/2.1/3.x]}
  994. Function SetEndOfJobStatus( EndOfJobFlag: Boolean ):Boolean;
  995. { When this function is called with EndOfJobFlag=False and control is returned
  996.   to the root COMMAND.COM, COMMAND.COM will NOT perform an EOJ action.     }
  997. Var regs:Registers;
  998. begin
  999. regs.AH:=$BB;
  1000. If EndOfJobFlag
  1001.  then regs.AL:=$01
  1002.  else regs.AL:=$00;
  1003. MsDos(Regs);
  1004. { AL now contains previous EOJ Flag }
  1005. Result:=$00;
  1006. SetEndOfJobStatus:=True;
  1007. end;
  1008.  
  1009. {DB.. [2.0/2.1/3.x]}
  1010. Function GetNumberOfLocalDrives( Var drives:Byte ):Boolean;
  1011. Var regs:registers;
  1012. begin
  1013. regs.ah:=$DB;
  1014. MsDos(Regs);
  1015. drives:=Regs.AL;
  1016. Result:=$00;
  1017. GetNumberOfLocalDrives:=TRUE;
  1018. end;
  1019.  
  1020. {B503: (Shell version >=3.01)}
  1021. Function GetTaskMode( Var taskMode:Byte):boolean;
  1022. Var regs:registers;
  1023. begin
  1024. Regs.AX:=$B503;
  1025. MsDos(Regs);
  1026. taskMode:=Regs.AL;
  1027. result:=0;
  1028. GetTaskMode:=TRUE;
  1029. end;
  1030.  
  1031. {B504: (shell version >=3.01)}
  1032. Function GetTaskModePointer( PtaskMode:Pointer ):boolean;
  1033. Var Regs:Registers;
  1034. begin
  1035. Regs.AX:=$B504;
  1036. MsDos(regs);
  1037. PtaskMode:=Ptr(regs.ES,regs.BX);
  1038. result:=0;
  1039. GetTaskModePointer:=TRUE;
  1040. end;
  1041.  
  1042. {=======SECONDARY FUNCTIONS===================================================}
  1043.  
  1044. {
  1045. Function template(   ):boolean;
  1046. Var regs:registers;
  1047. Var req  :record
  1048.           len:word;
  1049.           subFunc:byte;
  1050.  
  1051.           end;
  1052.     reply:record
  1053.           len:word;
  1054.           end;
  1055. Begin
  1056. WITH req
  1057. do begin
  1058.    len:=SizeOf(req)-2;
  1059.    subFunc:=$
  1060.  
  1061.    end;
  1062. Reply.len:=$FF;
  1063. With regs
  1064. do begin
  1065.    AX:=$E300;
  1066.    Ds:=seg(Req);
  1067.    si:=ofs(Req);
  1068.    Es:=seg(Reply);
  1069.    di:=ofs(Reply);
  1070.    MsDos(regs);
  1071.    result:=AL;
  1072.    end;
  1073. With reply
  1074. do begin
  1075.  
  1076.    end;
  1077. template:=(result=0)
  1078. end; }
  1079.  
  1080.  
  1081. {EF03 [2.0/2.1/3.x] secondary Function }
  1082. Function IsConnectionIDinUse( connID: byte ):boolean;
  1083. Type ptarr=^arr;
  1084.      arr=array[0..8*32] of byte;
  1085. Var regs:registers;
  1086. begin
  1087. If ((connID<1) or (ConnID>8))
  1088.  then IsConnectionIDInUse:=TRUE
  1089.  else begin
  1090.       regs.ax:=$EF03;
  1091.       MsDos(regs);
  1092.       IsConnectionIDinUse:=(ptarr(Ptr(regs.es,regs.si))^[(connID-1)*32] = $FF)
  1093.       end;
  1094. end;
  1095.  
  1096.  
  1097.  
  1098. Function GetUserAtConnection( ConnectionNbr:byte; var username: string):boolean;
  1099. {This function provides a shorter method of obtaining just the USERID.}
  1100. var id:LongInt;
  1101.     typ:word;
  1102.     time:NovTimeRec;
  1103. begin
  1104.  getUserAtConnection:=GetConnectionInformation(ConnectionNbr,username,typ,id,time);
  1105. end;
  1106.  
  1107.  
  1108. Function GetEffectiveConnectionID(Var connId:byte):boolean;
  1109. begin
  1110. if NOT (GetPreferredConnectionID(connId) and (connId<>0))
  1111.  then if NOT (GetDefaultConnectionID(ConnId) and (connId<>0))
  1112.        then GetPrimaryConnectionId(ConnId);
  1113. GetEffectiveConnectionID:=(result=$00);
  1114. end;
  1115.  
  1116.  
  1117. Function GetObjectLoginControl(ObjName:string; ObjType:word;
  1118.                                VAR LoginControlInfo:TloginControl):boolean;
  1119. { Caller must have access to the bindery property LOGIN_CONTROL.
  1120.   Default: you need to be supervisor-equivalent or the object the property
  1121.            is associated with. (reading your 'own' information)
  1122.  
  1123.   PasswordcontrolFlag:
  1124.   00 User is allowed to change PW.
  1125.   01 User is NOT allowed to change PW.
  1126.   02 User is allowed to change PW, but the new password must be unique.
  1127.   03 User is NOT allowed to change PW, and a new password, to be changed
  1128.      by the supervisor, must be unique.
  1129. }
  1130. Var LCpropVal:PropertyType;
  1131.     lc:record
  1132.        _AccExpDate          :array[1..3] of byte; {yy mm dd}
  1133.        _AccDisabled         :boolean;
  1134.        _PWexpDate           :array[1..3] of byte; {yy mm dd}
  1135.        _GraceLoginsRemaining:byte;
  1136.        _DaysBetwPWchanges   :word;
  1137.        _MaxGraceLogins      :byte;
  1138.        _minPWlen            :byte;
  1139.        _unknown1            :byte;
  1140.        _MaxConcConn         :byte;
  1141.        _loginTimes          :array[1..42] of byte;
  1142.        _LastLoginTime       :array[1..6] of byte; {yy mm dd hh mm ss}
  1143.        _PWcontrol           :byte;
  1144.        _unknown2            :array[1..6] of byte; {time of last intrusion??}
  1145.        _badLoginCount       :byte;
  1146.        _AccountResetTime    :LongInt; { minutes since 1/1/1985 }
  1147.        _lastIntruderAdress  :TinterNetworkAdress;
  1148.        end        ABSOLUTE LCpropVal;
  1149.     moreSegments:boolean;
  1150.     propFlags:byte;
  1151.  
  1152. begin
  1153. IF nwBindry.ReadPropertyValue(ObjName,ObjType,'LOGIN_CONTROL',1,
  1154.                               LCpropval,moreSegments,propFlags)
  1155.  then begin
  1156.       FillChar(LoginControlInfo,SizeOf(LoginControlInfo),#0);
  1157.       With LoginControlInfo
  1158.        do begin
  1159.           AccountDisabled           :=lc._AccDisabled;
  1160.           move(lc._AccExpDate[1],AccountExpirationDate.year,3);
  1161.           move(lc._PWexpDate[1],PasswordExpirationDate.year,3);
  1162.           MinimumPasswordLength     :=lc._minPWlen;
  1163.           PasswordControlFlag       :=lc._PWcontrol;
  1164.           DaysBetweenPasswordChanges:=swap(lc._DaysBetwPWchanges);
  1165.           Move(lc._lastLoginTime[1],LastLoginTime.year,6);
  1166.           GraceLoginsRemaining      :=lc._GraceLoginsRemaining;
  1167.           MaxGraceLoginsAllowed     :=lc._maxGraceLogins;
  1168.           BadLoginCount             :=lc._badLoginCount;
  1169.           {AccountResetTime         := .. }
  1170.           LastIntruderAdress        :=lc._LastIntruderAdress;
  1171.           LastIntruderAdress.socket :=swap(LastIntruderAdress.socket); {force lo-hi}
  1172.           MaxConcurrentConnections  :=lc._MaxConcConn;
  1173.           Move(lc._LoginTimes[1],LoginTimes[1],42);
  1174.  
  1175.           unknown1:=lc._unknown1;
  1176.           move(lc._unknown2[1],unknown2.year,6);
  1177.           end;
  1178.       end
  1179.  else result:=nwBindry.result;
  1180. end;
  1181.  
  1182.  
  1183. end. { end of unit nwConn }
  1184.  
  1185.